package com.elitel.frame.base.service.impl;

import com.elitel.common.utils.XCommonUtils;
import com.elitel.frame.base.component.RedisCacheDataBase;
import com.elitel.frame.base.component.exportprojectdata.DataBaseConnInfo;
import com.elitel.frame.base.service.BaseFieldenumService;
import com.elitel.frame.base.service.BaseShowfieldService;
import com.elitel.frame.main.dao.BaseMasterdetailMapper;
import com.elitel.frame.main.dao.BaseShowfieldMapper;
import com.elitel.frame.main.dao.CfgExtendMapper;
import com.elitel.frame.main.dao.CfgExtmasterMapper;
import com.elitel.frame.main.dao.ext.ExtBaseFieldaddonsMapper;
import com.elitel.frame.main.dao.ext.ExtBaseShowfieldMapper;
import com.elitel.frame.main.dao.ext.ExtCfgFieldMapper;
import com.elitel.frame.main.dao.ext.ExtCfgTableMapper;
import com.elitel.frame.main.entity.*;
import com.elitel.frame.main.entity.ext.BaseFieldaddonsExt;
import com.elitel.frame.main.entity.ext.BaseShowfieldExt;
import com.elitel.frame.main.entity.vo.BaseShowfieldVo;
import com.elitel.frame.main.entity.vo.ShowFieldVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author guoyanfei
 * @description 服务显示字段接口实现类
 * @date 2017/11/14
 */
@Service
public class BaseShowfieldServiceImpl implements BaseShowfieldService {
    @Autowired
    private CfgExtendMapper cfgExtendMapper;
    @Autowired
    private ExtCfgTableMapper extCfgTableMapper;
    @Autowired
    private ExtCfgFieldMapper extCfgFieldMapper;
    @Autowired
    private ExtBaseFieldaddonsMapper extBaseFieldaddonsMapper;
    @Autowired
    private BaseShowfieldMapper baseShowfieldMapper;
    @Autowired
    private ExtBaseShowfieldMapper extBaseShowfieldMapper;
    @Autowired
    private RedisCacheDataBase redisCacheDataBase;
    @Autowired
    private CfgExtmasterMapper cfgExtmasterMapper;
    @Autowired
    private BaseMasterdetailMapper baseMasterdetailMapper;
    @Autowired
    private BaseFieldenumService baseFieldenumService;
    @Autowired
    private DataBaseConnInfo dataBaseConnInfo;

    /**
     * @param serviceId(服务ID)
     * @return ShowFieldVo集合
     * @description 通过服务ID查询该服务的所有配置字段
     * @author guoyanfei
     * @date 2017/11/14
     */
    @Override
    public List<ShowFieldVo> getShowfieldByServiceId(String serviceId, String serviceType, String masterDetailId) {
        List<ShowFieldVo> showFieldVos = new ArrayList<ShowFieldVo>();
        if (XCommonUtils.isSingleTableService(serviceType)) {
            handleShowFieldOfSingleTable(serviceId, showFieldVos);

        } else if (XCommonUtils.isMasterSlaveTableService(serviceType)) {
            //主从表服务
            if (XCommonUtils.isMasterService(masterDetailId)) {
                //主表服务
                handleShowFieldOfMasterTable(serviceId, showFieldVos);
            } else {
                //从表服务
                handleShowFieldOfSlaveTable(masterDetailId, showFieldVos);
            }
        }

        //移除已配置好的服务显示字段
        List<BaseShowfield> baseShowFieldList = extBaseShowfieldMapper.getShowfieldByServiceId(serviceId, Integer.valueOf(serviceType), masterDetailId);
        if (XCommonUtils.isEmpty(baseShowFieldList))
            return showFieldVos;

        Map<String, List<ShowFieldVo>> showFieldVoListMap = showFieldVos.stream().collect(Collectors.groupingBy(ShowFieldVo::getFieldguid));
        for (BaseShowfield baseShowField : baseShowFieldList) {
            List<ShowFieldVo> showFieldVoList = showFieldVoListMap.get(baseShowField.getFieldaddonsguid());
            if (XCommonUtils.isEmpty(showFieldVoList))
                continue;

            showFieldVos.remove(showFieldVoList.get(0));
        }

        return showFieldVos;
    }

    // here is not use field
    @Override
    public List<BaseShowfieldExt> getNotExistsShowFieldInService(String serviceId, String serviceType, String masterDetailId) {
//		List<BaseShowfieldExt> baseShowFieldExtList = getShowfieldList(serviceId, serviceType,masterDetailId);
        List<BaseShowfieldExt> baseShowFieldExtList = new LinkedList<>();


        List<ShowFieldVo> showFieldVos = new ArrayList<ShowFieldVo>();
        if (XCommonUtils.isSingleTableService(serviceType)) {
            handleShowFieldOfSingleTable(serviceId, showFieldVos);

        } else if (XCommonUtils.isMasterSlaveTableService(serviceType)) {
            //主从表服务
            if (XCommonUtils.isMasterService(masterDetailId)) {
                //主表服务
                handleShowFieldOfMasterTable(serviceId, showFieldVos);
            } else {
                //从表服务
                handleShowFieldOfSlaveTable(masterDetailId, showFieldVos);
            }
        }
        // here is convert showFieldVos to BaseSHowfieldExt List
        for (ShowFieldVo showFieldVo : showFieldVos) {
            BaseShowfieldExt baseShowFieldExt = new BaseShowfieldExt();
            baseShowFieldExt.setFieldaddonsguid(showFieldVo.getFieldguid());
            baseShowFieldExt.setFieldname(showFieldVo.getFieldname());
            baseShowFieldExt.setFieldnameCn(showFieldVo.getFieldnameCn());
            baseShowFieldExtList.add(baseShowFieldExt);
        }

        //移除已配置好的服务显示字段
        List<BaseShowfield> baseShowFieldList = extBaseShowfieldMapper.getShowfieldByServiceId(serviceId, Integer.valueOf(serviceType), masterDetailId);
        if (XCommonUtils.isEmpty(baseShowFieldList))
            return baseShowFieldExtList;

        Map<String, List<BaseShowfieldExt>> showFieldVoListMap = baseShowFieldExtList.stream().collect(Collectors.groupingBy(BaseShowfieldExt::getFieldaddonsguid));
        for (BaseShowfield baseShowField : baseShowFieldList) {
            List<BaseShowfieldExt> showFieldVoList = showFieldVoListMap.get(baseShowField.getFieldaddonsguid());
            if (XCommonUtils.isEmpty(showFieldVoList))
                continue;

            baseShowFieldExtList.remove(showFieldVoList.get(0));
        }

        return baseShowFieldExtList;
    }


    private void handleShowFieldOfSlaveTable(String masterDetailId, List<ShowFieldVo> showFieldVos) {
        BaseMasterdetail baseMasterdetail = baseMasterdetailMapper.selectByPrimaryKey(masterDetailId);
        if (baseMasterdetail != null) {
            String dtConfigId = baseMasterdetail.getDtConfigId();
            showFieldVos.addAll(getAllShowFieldVo(dtConfigId));
        }
    }


    private void handleShowFieldOfMasterTable(String serviceId, List<ShowFieldVo> showFieldVos) {
        CfgExtmaster cfgExtmaster = cfgExtmasterMapper.selectByPrimaryKey(serviceId);
        if (cfgExtmaster != null) {
            String dtConfigId = cfgExtmaster.getDtConfigId();
            showFieldVos.addAll(getAllShowFieldVo(dtConfigId));
        }
    }


    private void handleShowFieldOfSingleTable(String serviceId, List<ShowFieldVo> showFieldVos) {
        //单表服务
        CfgExtend cfgExtend = cfgExtendMapper.selectByPrimaryKey(serviceId);
        if (cfgExtend != null) {
            String dtConfigId = cfgExtend.getDtConfigId();
            showFieldVos.addAll(getAllShowFieldVo(dtConfigId));
        }
    }


    /**
     * @param baseShowfields
     * @return 新增条数
     * @description 批量新增服务显示字段信息
     * @author guoyanfei
     * @date 2017/11/15
     */
    @Override
    public Integer addShowfield(List<BaseShowfield> baseShowfields) {
//		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int result = 0;
        if (baseShowfields != null && baseShowfields.size() > 0) {
            int showorder = 1;
            String databaseType = dataBaseConnInfo.dataBaseType;
            for (BaseShowfield baseShowfield : baseShowfields) {
                Integer maxorder = 0;
                /*switch (databaseType) {
                    case "oracle":
                        maxorder = extBaseShowfieldMapper.selectMaxshowOrderOracle(
                                baseShowfield.getServiceid(), baseShowfield.getMasterdetailid());

                        break;
                    case "mysql":
                    case "sqlite":
                    case "h2":
                    case DataSourceType.POSTGRES:
                        maxorder = extBaseShowfieldMapper.selectMaxshowOrderMysql(
                                baseShowfield.getServiceid(), baseShowfield.getMasterdetailid());
                        break;
                }*/
                maxorder = extBaseShowfieldMapper.selectMaxshowOrderMysql(baseShowfield.getServiceid(), baseShowfield.getMasterdetailid());
                if (maxorder != null) {
                    showorder = maxorder + 1;
                }
                baseShowfield.setGuid(UUID.randomUUID().toString());
                baseShowfield.setShoworder(showorder);
                baseShowfield.setCreatedate(new Date());
                result += baseShowfieldMapper.insertSelective(baseShowfield);

                //刷新服务
                redisCacheDataBase.refreshBaseShowfield(baseShowfield.getServiceid(), baseShowfield.getServicetype().toString(), baseShowfield.getMasterdetailid().toString());
            }
        }
        return result;
    }


    /**
     * @param serviceId(服务ID)
     * @param serviceType(服务类型)
     * @return BaseShowfieldExt集合
     * @description 通过服务Id和服务类型查询该服务已配置的显示字段信息
     * @author guoyanfei
     * @date 2017/11/15
     */
    @Override
    public List<BaseShowfieldExt> getShowfieldList(String serviceId, String serviceType, String masterDetailId) {
        String databaseType = dataBaseConnInfo.dataBaseType;

        //单表服务
        if (XCommonUtils.isSingleTableService(serviceType))
            return handleSingleService(serviceId, databaseType, Integer.valueOf(serviceType));

        //主从表服务
        if (XCommonUtils.isMasterSlaveTableService(serviceType)) {
            if (XCommonUtils.isMasterService(masterDetailId))
                return handleMasterSlaveTableMasterService(masterDetailId, serviceId, databaseType, Integer.valueOf(serviceType));

            if (XCommonUtils.isSlaveService(masterDetailId))
                return handleMasterSlaveTableSlaveService(masterDetailId, serviceId, databaseType, Integer.valueOf(serviceType));
        }

        return null;
    }

    private List<BaseShowfieldExt> handleSingleService(String serviceId, String databaseType, Integer serviceType) {
        List<BaseShowfieldExt> baseShowFieldExtList = null;
        CfgExtend cfgExtend = cfgExtendMapper.selectByPrimaryKey(serviceId);
        if (cfgExtend == null)
            return baseShowFieldExtList;

        CfgTable cfgTable = extCfgTableMapper.getInfoByDtconfigId(cfgExtend.getDtConfigId());
        if (cfgTable == null)
            return baseShowFieldExtList;

        //数据表
        if (XCommonUtils.isOriginSingleTableType(cfgTable.getDtTabletype())) {
            /*switch (databaseType) {
                case "oracle":
                    baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoTable(serviceId, serviceType, "");
                    break;
                case "mysql":
                case "sqlite":
                case "h2":
                case DataSourceType.POSTGRES:
                    baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoTableMysql(serviceId, serviceType, "");
                    break;
            }*/
            baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoTableMysql(serviceId, serviceType, "");
            if (baseShowFieldExtList==null||baseShowFieldExtList.isEmpty()) {
                List<BaseShowfield> showfieldByServiceId = extBaseShowfieldMapper.getShowfieldByServiceId(serviceId, 1, null);
                for (BaseShowfield baseShowfield : showfieldByServiceId) {
                    BaseShowfieldExt baseShowfieldExt = new BaseShowfieldExt();
                    BeanUtils.copyProperties(baseShowfield, baseShowfieldExt);
                    baseShowFieldExtList.add(baseShowfieldExt);
                }
            }
        }

        //视图
        if (XCommonUtils.isViewTableType(cfgTable.getDtTabletype())) {
            /*switch (databaseType) {
                case "oracle":
                    baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoView(serviceId, serviceType, "");
                    break;
                case "mysql":
                case "sqlite":
                case "h2":
                case DataSourceType.POSTGRES:
                    baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoViewMysql(serviceId, serviceType, "");
                    break;
            }*/
            baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoViewMysql(serviceId, serviceType, "");
        }

        return baseShowFieldExtList;
    }

    private List<BaseShowfieldExt> handleMasterSlaveTableMasterService(String masterDetailId, String serviceId, String databaseType, Integer serviceType) {
        CfgExtmaster cfgExtmaster = cfgExtmasterMapper.selectByPrimaryKey(serviceId);
        if (cfgExtmaster == null)
            return null;

        String dtConfigId = cfgExtmaster.getDtConfigId();
        CfgTable cfgTable = extCfgTableMapper.getInfoByDtconfigId(dtConfigId);
        if (cfgTable == null)
            return null;

        return handleMasterSlaveTableBaseService(cfgTable, masterDetailId, serviceId, databaseType, serviceType);
    }


    private List<BaseShowfieldExt> handleMasterSlaveTableSlaveService(String masterDetailId, String serviceId, String databaseType, Integer serviceType) {

        BaseMasterdetail baseMasterdetail = baseMasterdetailMapper.selectByPrimaryKey(masterDetailId);
        if (baseMasterdetail == null)
            return null;

        String dtConfigId = baseMasterdetail.getDtConfigId();
        CfgTable cfgTable = extCfgTableMapper.getInfoByDtconfigId(dtConfigId);
        if (cfgTable == null)
            return null;

        return handleMasterSlaveTableBaseService(cfgTable, masterDetailId, serviceId, databaseType, serviceType);
    }

    private List<BaseShowfieldExt> handleMasterSlaveTableBaseService(CfgTable cfgTable, String masterDetailId, String serviceId, String databaseType, Integer serviceType) {
        List<BaseShowfieldExt> baseShowFieldExtList = null;

        if (XCommonUtils.isOriginSingleTableType(cfgTable.getDtTabletype())) {
            //数据表
            /*switch (databaseType) {
                case "oracle":
                    baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoTable(serviceId, serviceType, masterDetailId);
                    break;
                case "mysql":
                case "sqlite":
                case "h2":
                case DataSourceType.POSTGRES:
                    baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoTableMysql(serviceId, serviceType, masterDetailId);
                    break;
            }*/
            baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoTableMysql(serviceId, serviceType, masterDetailId);
        }

        if (XCommonUtils.isViewTableType(cfgTable.getDtTabletype())) {
            //视图
            /*switch (databaseType) {
                case "oracle":
                    baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoView(serviceId, serviceType, masterDetailId);
                    break;
                case "mysql":
                case "sqlite":
                case "h2":
                case DataSourceType.POSTGRES:
                    baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoViewMysql(serviceId, serviceType, masterDetailId);
                    break;
            }*/
            baseShowFieldExtList = extBaseShowfieldMapper.getShowfieldByPagetoViewMysql(serviceId, serviceType, masterDetailId);
        }
        return baseShowFieldExtList;
    }


    /**
     * @param guids(guid以','隔开)
     * @return 删除条数
     * @description 批量删除服务配置好的显示字段信息
     * @author guoyanfei
     * @date 2017/11/15
     */
    @Override
    public Integer deleteShowfieldByguids(String guids) {
        Integer result = 0;
        String[] strguid = guids.split(",");
        for (String guid : strguid) {
            //刷新服务
            BaseShowfield baseShowfield = baseShowfieldMapper.selectByPrimaryKey(guid);
            if (baseShowfield.getMasterdetailid() == null) {
                baseShowfield.setMasterdetailid("");
            }
            //删除数据
            result += baseShowfieldMapper.deleteByPrimaryKey(guid);

            if (baseShowfield != null) {
                redisCacheDataBase.refreshBaseShowfield(baseShowfield.getServiceid(), baseShowfield.getServicetype().toString(), baseShowfield.getMasterdetailid());
            }
        }

        return result;
    }

    /**
     * @param baseShowfield(显示字段实体)
     * @return 修改条数
     * @description 修改显示字段信息
     * @author guoyanfei
     * @date 2017/11/15
     */
    @Override
    public Integer updateShowfield(BaseShowfield baseShowfield) {
        //修改
        Integer result = baseShowfieldMapper.updateByPrimaryKeySelective(baseShowfield);
        //刷新服务
        redisCacheDataBase.refreshBaseShowfield(baseShowfield.getServiceid(), baseShowfield.getServicetype().toString(), baseShowfield.getMasterdetailid());

        return result;
    }

    @Override
    public Integer updateShowfieldList(List<BaseShowfield> baseShowfieldList) {
        if (baseShowfieldList == null)
            return 0;
        Integer modifyCount = 0;

        for (BaseShowfield baseShowfield : baseShowfieldList) {
            modifyCount += updateShowfield(baseShowfield);
        }

        return modifyCount;
    }


    /**
     * @param dtConfigId(表标识)
     * @return ShowFieldVo集合
     * @description 通过表标识查询所有配置的字段信息
     * @author guoyanfei
     * @date 2017/11/20
     */
    @Override
    public List<ShowFieldVo> getAllShowFieldVo(String dtConfigId) {
        List<ShowFieldVo> showFieldVos = new ArrayList<ShowFieldVo>();
        CfgTable cfgTable = extCfgTableMapper.getInfoByDtconfigId(dtConfigId);
        if (cfgTable == null)
            return showFieldVos;

        if (XCommonUtils.isOriginSingleTableType(cfgTable.getDtTabletype())) {
            //元数据表
            List<CfgField> cfgFields = extCfgFieldMapper.getAllFieldList(dtConfigId);
            if (XCommonUtils.isNotEmpty(cfgFields)) {
                for (CfgField cfgField : cfgFields) {
                    ShowFieldVo showFieldVo = new ShowFieldVo();
                    showFieldVo.setFieldguid(cfgField.getGuid());
                    showFieldVo.setFieldname(cfgField.getDfName());
                    showFieldVo.setFieldnameCn(cfgField.getDfNameCn());
                    showFieldVo.setTablename(cfgTable.getDtNameCn());
                    showFieldVo.setAltertablename("AA");
                    showFieldVos.add(showFieldVo);
                }
            }
            //字段枚举
            List<BaseFieldenum> baseFieldenums = baseFieldenumService.getBaseFieldenumList(dtConfigId);
            if (XCommonUtils.isNotEmpty(baseFieldenums)) {
                for (BaseFieldenum baseFieldenum : baseFieldenums) {
                    ShowFieldVo showFieldVo = new ShowFieldVo();
                    showFieldVo.setFieldguid(baseFieldenum.getGuid());
                    showFieldVo.setFieldname(baseFieldenum.getEnumcode());
                    showFieldVo.setFieldnameCn(baseFieldenum.getEnumname());
                    showFieldVo.setTablename(cfgTable.getDtNameCn());
                    showFieldVo.setAltertablename("AA");
                    showFieldVos.add(showFieldVo);
                }
            }
        } else if (XCommonUtils.isViewTableType(cfgTable.getDtTabletype())) {
            //视图
            List<BaseFieldaddonsExt> baseFieldaddonsExts = extBaseFieldaddonsMapper.getBaseFieldaddonsByPage(dtConfigId);
            if (XCommonUtils.isNotEmpty(baseFieldaddonsExts)) {
                for (BaseFieldaddonsExt baseFieldaddonsExt : baseFieldaddonsExts) {
                    ShowFieldVo showFieldVo = new ShowFieldVo();
                    showFieldVo.setFieldguid(baseFieldaddonsExt.getGuid());
                    short ismodf = 1;
                    if (baseFieldaddonsExt.getIsmodfname() != null && baseFieldaddonsExt.getIsmodfname().equals(ismodf)) {
                        showFieldVo.setFieldname(baseFieldaddonsExt.getModifieldname());
                    } else {
                        showFieldVo.setFieldname(baseFieldaddonsExt.getFieldname());
                    }
                    if (baseFieldaddonsExt.getIsmodfcaption() != null && baseFieldaddonsExt.getIsmodfcaption().equals(ismodf)) {
                        showFieldVo.setFieldnameCn(baseFieldaddonsExt.getModifieldcaption());
                    } else {
                        showFieldVo.setFieldnameCn(baseFieldaddonsExt.getFieldnameCn());
                    }
                    showFieldVo.setTablename(cfgTable.getDtNameCn());
                    showFieldVo.setAltertablename(baseFieldaddonsExt.getAltername());
                    showFieldVos.add(showFieldVo);
                }
            }
        }

        return showFieldVos;
    }

    @Override
    public List<CfgTableFieldCustomAlias> getCfgTablePrimaryKeyCustomAliasByServiceId(Integer tableType, String serviceId) {
        List<CfgTableFieldCustomAlias> cfgTableFieldCustomAliasList = null;

        if (XCommonUtils.isOriginSingleTableType(tableType))
            cfgTableFieldCustomAliasList = extBaseShowfieldMapper.getCfgTablePrimaryKeyCustomAliasByServiceIdForTable(serviceId);
        else
            cfgTableFieldCustomAliasList = extBaseShowfieldMapper.getCfgTablePrimaryKeyCustomAliasByServiceIdForView(serviceId);

        return Optional.ofNullable(cfgTableFieldCustomAliasList).orElse(new LinkedList<>());
    }

    @Override
    public List<BaseShowfieldVo> selectByServiceCodes(List<String> serviceCodes) {
        return baseShowfieldMapper.selectByServiceCodes(serviceCodes);
    }


}
